use std::env;
use std::error::Error;

type Output = Result<(), Box<dyn Error>>;

fn main() -> Output {
    // this is wild
    #[cfg(target_os = "macos")]
    {
        println!("cargo:rustc-link-lib=framework=foundation");
        println!("cargo:rustc-link-lib=framework=security");
    }

    let target = env::var("TARGET").ok();
    let host = env::var("HOST").ok();

    // This is an enormous hack.  Normally on Linux, Ruby would use
    // libcrypt functions libruby-static.a would contain references to
    // such functions, and we would need to specify -lcrypt via the
    // link line below.
    //
    // But on a vanilla cross-compilation setup on Ubuntu, libcrypt
    // doesn't exist for cross-compilation.  Ruby is OK with that (its
    // configure script will detect the absence of a linkable
    // libcrypt) and therefore in such a situation we would not need
    // to specify -lcrypt.  Ruby's rbconfig.rb file, generated by its
    // configure script, will helpfully include information about the
    // presence or absence of libcrypt on the system.
    //
    // But we can't access that Ruby configuration information here:
    // we have no control over when the build script for this crate
    // runs vs. the build script for librubyfmt, and it is the latter
    // that configures Ruby and generates the very files that we would
    // need to look at to make the determination of whether to specify
    // -lcrypt.
    //
    // So instead we make an assumption: if our target and host are
    // different, then we're running in a vanilla-ish Ubuntu
    // environment where libcrypt wouldn't be available.  In a more
    // full-featured cross-compilation setup, this assumption is
    // invalid, but it works well enough for our purposes.
    if cfg!(target_os = "linux") && target.zip(host).map(|(t, h)| t == h).unwrap_or(false) {
        println!("cargo:rustc-link-lib=dylib=crypt");
    }

    Ok(())
}
